<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.2.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"hanayabuki.gitee.io","root":"/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","width":240,"display":"always","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
  </script>

  <meta name="description" content="🍩 本节课学习更加丰富的面向对象特性.">
<meta property="og:type" content="article">
<meta property="og:title" content="南邮校科协-C#组授课(3)">
<meta property="og:url" content="http://hanayabuki.gitee.io/2020/11/10/%E5%8D%97%E9%82%AE%E6%A0%A1%E7%A7%91%E5%8D%8F-C-%E7%BB%84%E6%8E%88%E8%AF%BE-3/index.html">
<meta property="og:site_name" content="花枝丸🍥的博客">
<meta property="og:description" content="🍩 本节课学习更加丰富的面向对象特性.">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1604997545359&di=d3199514f2de1b4fd820a2213818ad3a&imgtype=0&src=http://04.imgmini.eastday.com/mobile/20180801/20180801184514_fcf5c318be0507e47143193c96388c8d_1.jpeg">
<meta property="article:published_time" content="2020-11-10T13:53:25.000Z">
<meta property="article:modified_time" content="2020-11-30T13:57:48.187Z">
<meta property="article:author" content="Hanamaru🍥Yabuki">
<meta property="article:tag" content="C#">
<meta property="article:tag" content="授课">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1604997545359&di=d3199514f2de1b4fd820a2213818ad3a&imgtype=0&src=http://04.imgmini.eastday.com/mobile/20180801/20180801184514_fcf5c318be0507e47143193c96388c8d_1.jpeg">

<link rel="canonical" href="http://hanayabuki.gitee.io/2020/11/10/%E5%8D%97%E9%82%AE%E6%A0%A1%E7%A7%91%E5%8D%8F-C-%E7%BB%84%E6%8E%88%E8%AF%BE-3/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>南邮校科协-C#组授课(3) | 花枝丸🍥的博客</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">花枝丸🍥的博客</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
      <p class="site-subtitle" itemprop="description">记录自己作为CS学生的点滴</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-about">

    <a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签<span class="badge">7</span></a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类<span class="badge">5</span></a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档<span class="badge">13</span></a>

  </li>
  </ul>
</nav>




</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>
  <div class="reading-progress-bar"></div>

  <a href="https://github.com/HanaYabuki" class="github-corner" title="Follow me on GitHub" aria-label="Follow me on GitHub" rel="noopener" target="_blank"><svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://hanayabuki.gitee.io/2020/11/10/%E5%8D%97%E9%82%AE%E6%A0%A1%E7%A7%91%E5%8D%8F-C-%E7%BB%84%E6%8E%88%E8%AF%BE-3/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="Hanamaru🍥Yabuki">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="花枝丸🍥的博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          南邮校科协-C#组授课(3)
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2020-11-10 21:53:25" itemprop="dateCreated datePublished" datetime="2020-11-10T21:53:25+08:00">2020-11-10</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2020-11-30 21:57:48" itemprop="dateModified" datetime="2020-11-30T21:57:48+08:00">2020-11-30</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E6%8E%88%E8%AF%BE/" itemprop="url" rel="index"><span itemprop="name">授课</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <p>🍩 本节课学习更加丰富的面向对象特性.</p>
<a id="more"></a>

<hr>
<h1 id="更多的面向对象-和-数据结构"><a href="#更多的面向对象-和-数据结构" class="headerlink" title="更多的面向对象 和 数据结构"></a>更多的面向对象 和 数据结构</h1><p>上节课中，我们学习了面向对象的很多知识点。对面向对象的三大特性 <strong>封装，继承，多态</strong> 都有了很好的理解，想必大家也一定进行了丰富的应用。</p>
<p>这节课我们将对上节课的内容进行补充和进阶。</p>
<hr>
<h2 id="〇、补充历史遗留问题"><a href="#〇、补充历史遗留问题" class="headerlink" title="〇、补充历史遗留问题"></a>〇、补充历史遗留问题</h2><p>第一节课本来应该讲 <strong>枚举</strong> 的，忘了….想了想，常量更重要，也忘了讲了….</p>
<h3 id="const"><a href="#const" class="headerlink" title="const"></a>const</h3><p>这个东西非常简单，以至于我都要把他忘了。</p>
<p>在C语言中，我们经常会写出这样的代码</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">define</span> pi 3.1415926535897932384626</span></span><br></pre></td></tr></table></figure>

<p>我们都知道，C语言的宏定义本质上是为了复用同一个长长的常量。但这种字符串替换编译的实现方案显然是愚蠢的。C# 提供了 <strong>常量</strong> 概念来解决这个问题。（C++中也提供了）</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="built_in">double</span> PI = <span class="number">3.1415926535</span>;</span><br></pre></td></tr></table></figure>

<p>值得注意的是，C# 所有内容基于类实现，所以….</p>
<h3 id="枚举"><a href="#枚举" class="headerlink" title="枚举"></a>枚举</h3><p>枚举是一组命名整型常量。枚举类型是使用 enum 关键字声明的。</p>
<p>C# 枚举是值类型。换句话说，枚举包含自己的值，且不能继承或传递继承。</p>
<p>声明 enum 变量</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">enum</span> &lt;enum_name&gt;</span><br><span class="line">&#123; </span><br><span class="line">    enumeration list </span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>其中，</p>
<ul>
<li>enum_name 指定枚举的类型名称。</li>
<li>enumeration list 是一个用逗号分隔的标识符列表。</li>
</ul>
<p>枚举列表中的每个符号代表一个整数值，一个比它前面的符号大的整数值。默认情况下，第一个枚举符号的值是 0. 例如 ：</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">enum</span> Days &#123; Sun, Mon, tue, Wed, thu, Fri, Sat &#125;;</span><br></pre></td></tr></table></figure>
<p>使用如下：</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> System;</span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">CS_ConsoleApp</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="keyword">class</span> <span class="title">Program</span></span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">enum</span> Day &#123; Sun, Mon, Tue, Wed, Thu, Fri, Sat &#125;;</span><br><span class="line"></span><br><span class="line">		<span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span>(<span class="params"><span class="built_in">string</span>[] args</span>)</span></span><br><span class="line"><span class="function"></span>		&#123;</span><br><span class="line">			Day day = Day.Mon;</span><br><span class="line">			Console.WriteLine(day);</span><br><span class="line">			Console.ReadKey();</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>输出结果 也为 <code>枚举的被定义字串</code></p>
<p>其实，枚举只是对我们写代码的一种规范要求，它旨在减少宏定义的滥用，让编码更加轻便优雅。 </p>
<h3 id="out-引用传参"><a href="#out-引用传参" class="headerlink" title="out 引用传参"></a>out 引用传参</h3><p>上节课我们介绍了 ref 引用传参，ref 传参会引用被传入的参数，函数运行结束后，对所传参数的运算会被保留。</p>
<p>而 out 传参和 ref 传参有所差异。out 传参前，我们不必为所传参数赋初始值，与之对应的，我们需要在接收参数的函数结束前，至少为 out 赋值一次</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Up</span>(<span class="params"><span class="keyword">ref</span> <span class="built_in">int</span> x</span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    x++;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span>(<span class="params"><span class="built_in">string</span>[] args</span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">int</span> a = <span class="number">5</span>;</span><br><span class="line">    Up(<span class="keyword">ref</span> a);</span><br><span class="line">    Console.WriteLine(a);</span><br><span class="line">    Console.ReadKey();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这串代码 如果只把 <code>ref</code> 改成 <code>out</code> 是行不通的，因为 <code>out</code> 传参的内容只有参数的地址，不包含参数的值。换句话讲，传入的 <code>x</code> 相当于一个没有赋值过的空变量。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">XtoSix</span>(<span class="params"><span class="keyword">out</span> <span class="built_in">int</span> x</span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    x = <span class="number">6</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span>(<span class="params"><span class="built_in">string</span>[] args</span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">int</span> a = <span class="number">5</span>;</span><br><span class="line">    XtoSix(<span class="keyword">out</span> a);</span><br><span class="line">    Console.WriteLine(a);</span><br><span class="line">    Console.ReadKey();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这段代码是合法的。</p>
<p>从底层上理解： </p>
<ul>
<li><p>ref将参数的参数值和引用都传入方法中,所以ref的参数的初始化必须在方法外部,进行,也就是ref的参数必须有初始化值,否则程序会报错</p>
</li>
<li><p>out不会将参数的参数值传入方法中,只会将参数的引用传入方法中,所以参数的初始化工作必须在其对用方法中进行,否则程序会报错</p>
</li>
</ul>
<p>如果大家对C语言或者C++的指针有所研究，应该会很好理解。</p>
<p>值得注意的是：<code>ref</code> 和 <code>out</code> 并不构成重载。</p>
<h3 id="字段和属性"><a href="#字段和属性" class="headerlink" title="字段和属性"></a>字段和属性</h3><figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">namespace</span> <span class="title">CS_ConsoleApp</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="keyword">class</span> <span class="title">Box</span></span><br><span class="line">	&#123;</span><br><span class="line">		<span class="comment">// 这是字段</span></span><br><span class="line">		<span class="keyword">private</span> <span class="built_in">int</span> size;</span><br><span class="line"></span><br><span class="line">		<span class="comment">// 这是属性</span></span><br><span class="line">		<span class="keyword">public</span> <span class="built_in">int</span> Size &#123;</span><br><span class="line">			<span class="keyword">get</span></span><br><span class="line">			&#123;</span><br><span class="line">				<span class="keyword">return</span> size;</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">set</span></span><br><span class="line">			&#123;</span><br><span class="line">				<span class="keyword">value</span> = size;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<hr>
<p>进入本节课的主题：面向对象的更多细节</p>
<h2 id="一、静态-static"><a href="#一、静态-static" class="headerlink" title="一、静态 static"></a>一、静态 <code>static</code></h2><p>细心点的同学应该已经发现了，程序中出现了许多 <code>static</code> 关键字。他是蓝色的，说明他是一个程序保留字。</p>
<p><code>static</code> ，字面意思：静态的，不变的。在某个类中只有一个，不会因实例化对象的不同而不同。</p>
<p><code>static</code> 可以修饰类、字段、属性、方法等。如一个方法前加上 <code>static</code> 修饰后要对其进行调用可以直接通过类名点出来，不用再对类进行实例化。</p>
<p>我们仍然使用宝可梦作为例子讲解今天的内容。<br><img data-src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1604997545359&di=d3199514f2de1b4fd820a2213818ad3a&imgtype=0&src=http://04.imgmini.eastday.com/mobile/20180801/20180801184514_fcf5c318be0507e47143193c96388c8d_1.jpeg" alt="Pokemon world map"></p>
<h3 id="1-静态成员"><a href="#1-静态成员" class="headerlink" title="1. 静态成员"></a>1. 静态成员</h3><p>静态成员比较容易理解。</p>
<p>我们通常声明的 类的成员，声明结果是属于对象的。当我们实例化一个对象时，对应的内存空间被开辟。 而 静态成员 是属于一个类的，只要这个类被定义好了，对应的内存空间就被开辟了。</p>
<p>当然，<strong>每个类</strong>的<strong>每个成员</strong>只被定义一次。</p>
<p>不同的是，静态成员可以在被定义的时候初始化，就像普通的局部变量一样。</p>
<p>我们用 <em>宝可梦大陆</em> 来作为例子</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> System;</span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">CS_ConsoleApp</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="keyword">class</span> <span class="title">PokemonWorld</span></span><br><span class="line">	&#123;</span><br><span class="line">		<span class="keyword">static</span> <span class="built_in">int</span> pokemonNumber = <span class="number">0</span>;</span><br><span class="line">		<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">newPokemon</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"></span>		&#123;</span><br><span class="line">			++pokemonNumber;</span><br><span class="line">			Console.WriteLine(<span class="string">&quot;生成了新的宝可梦&quot;</span>);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">showNumber</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"></span>		&#123;</span><br><span class="line">			Console.WriteLine(<span class="string">$&quot;世界的宝可梦数量有<span class="subst">&#123;pokemonNumber&#125;</span>只&quot;</span>);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>主函数内容如下：</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> System;</span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">CS_ConsoleApp</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="keyword">class</span> <span class="title">Program</span></span><br><span class="line">	&#123;</span><br><span class="line">		<span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span>(<span class="params"><span class="built_in">string</span>[] args</span>)</span></span><br><span class="line"><span class="function"></span>		&#123;</span><br><span class="line">			PokemonWorld kanto = <span class="keyword">new</span> PokemonWorld(); <span class="comment">// 关都地区</span></span><br><span class="line">			<span class="keyword">for</span> (<span class="built_in">int</span> i=<span class="number">0</span>;i&lt;<span class="number">10</span>;++i)</span><br><span class="line">			&#123;</span><br><span class="line">				kanto.newPokemon();</span><br><span class="line">			&#125;</span><br><span class="line">			PokemonWorld hoenn = <span class="keyword">new</span> PokemonWorld(); <span class="comment">// 丰源地区</span></span><br><span class="line">			<span class="keyword">for</span> (<span class="built_in">int</span> i = <span class="number">0</span>; i &lt; <span class="number">10</span>; ++i)</span><br><span class="line">			&#123;</span><br><span class="line">				hoenn.newPokemon();</span><br><span class="line">			&#125;</span><br><span class="line"></span><br><span class="line">			kanto.showNumber();</span><br><span class="line">			Console.ReadKey();</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>我们可以看到，每次生成新宝可梦，本地的宝可梦就会增加一只。结果被存储到一个公用的静态变量中，最后的结果是两个地区的宝可梦总和。说明 <code>static int pokemonNumber</code> 成员是被每一个对象共用的。</p>
<blockquote>
<p>Tips:<br>C# 中，常量 <code>const</code> 被默认作为静态变量实现。</p>
</blockquote>
<h3 id="2-静态方法"><a href="#2-静态方法" class="headerlink" title="2. 静态方法"></a>2. 静态方法</h3><p>细心的同学应该又发现了：Main是一个静态的方法。（</p>
<p>上节课中，我们在讲函数的时候有提及</p>
<blockquote>
<p>这里我们声明了一个静态（static）方法，来保证 Main 函数里面可以直接简单的调用他。（static关键字的含义我们会在接下来的面向对象中学习，别骂了别骂了，不挖坑了，马上就讲）</p>
</blockquote>
<p>上节课说讲没来得及（x</p>
<p>静态方法很特殊。和静态成员类似， <strong>静态方法属于一个类，而不属于某一个对象。</strong> 我们调用的时候可以直接通过类名调用，而不需要实例化一个类。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Console.WriteLine(<span class="string">&quot;Hello World.&quot;</span>);</span><br><span class="line"><span class="comment">// 这就是一个静态方法，他调用了 Console 类中的静态方法 WriteLine。</span></span><br></pre></td></tr></table></figure>

<p>因为这一关键特性，导致了：</p>
<ul>
<li>静态方法最多只能访问静态成员，调用静态方法，不能访问非静态成员，调用非静态方法。（因为即使可以访问非静态，程序也并不知道这个非静态成员指的是哪一个实例对象）</li>
<li>静态方法不能用实例调用，只能用类调用。</li>
</ul>
<p>在上一个例子中，我们很容易想到，可以把 <strong>获取宝可梦总数量</strong> 的方法改写为静态</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">showNumber</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    Console.WriteLine(<span class="string">$&quot;世界的宝可梦数量有<span class="subst">&#123;pokemonNumber&#125;</span>只&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>调用也改为静态调用</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">PokemonWorld.showNumber();</span><br></pre></td></tr></table></figure>

<p>这样写更符合程序本身的逻辑含义。</p>
<h3 id="3-静态类"><a href="#3-静态类" class="headerlink" title="3. 静态类"></a>3. 静态类</h3><p><strong>静态类与非静态类的重要区别在于静态类没有实例。</strong></p>
<p>静态类的本质是一个抽象的密封类，他密封了许多有共同含义的元素，所以不能被继承，也不能被实例化。</p>
<p>在声明一个类时使用static关键字，具有两个方面的意义：</p>
<ul>
<li>防止程序员写代码来实例化该静态类</li>
<li>防止在类的内部声明任何非静态字段或方法。</li>
</ul>
<p>代码实现不给出来了，可以看一下 <code>System.Console</code> 的源码</p>
<h3 id="4-静态构造函数"><a href="#4-静态构造函数" class="headerlink" title="4. 静态构造函数"></a>4. 静态构造函数</h3><p>和构造函数的有些区别，他在本类的第一次使用前被调用（小细节），仅仅用于初始化本类所有静态成员。</p>
<p>我们根据这一特性改写 宝可梦的计数逻辑。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">static</span> <span class="built_in">int</span> pokemonNumber;</span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="title">PokemonWorld</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    Console.WriteLine(<span class="string">&quot;世界已被重置&quot;</span>);</span><br><span class="line">    pokemonNumber = <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>Tips:<br>  如果在主函数最开始打印字符串，会发现打印的字符串确实在第一行，也就是说，静态构造函数不是在程序最开始被调用的，而是等待第一次的使用</p>
</blockquote>
<h2 id="二、更多的静态多态性：运算符重载-和-内置方法重载"><a href="#二、更多的静态多态性：运算符重载-和-内置方法重载" class="headerlink" title="二、更多的静态多态性：运算符重载 和 内置方法重载"></a>二、更多的静态多态性：运算符重载 和 内置方法重载</h2><h3 id="运算符重载"><a href="#运算符重载" class="headerlink" title="运算符重载"></a>运算符重载</h3><p>早在上节课，我们说过，定义了一个类，就是封装了一种数据类型。对于数据类型，通常是可以进行四则运算的。</p>
<p>而运算符重载的出现，就是为了让我们给一个类提供进行运算的能力，让我们能够精确控制其细节。</p>
<p>语法很简单，类似于声明一个公开的静态函数</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="title">operator</span>&lt;*&gt; (<span class="params">&lt;<span class="keyword">params</span>&gt;</span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    &lt;statement&gt;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>我们暂时不使用宝可梦举例子，毕竟宝可梦不能进行四则运算。</p>
<p>我们声明一个长方形类。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> System;</span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">CS_ConsoleApp</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="keyword">class</span> <span class="title">Rectangle</span></span><br><span class="line">	&#123;</span><br><span class="line">		<span class="keyword">private</span> <span class="built_in">double</span> width;</span><br><span class="line">		<span class="keyword">private</span> <span class="built_in">double</span> height;</span><br><span class="line"></span><br><span class="line">		<span class="function"><span class="keyword">public</span> <span class="title">Rectangle</span>(<span class="params"><span class="built_in">double</span> w, <span class="built_in">double</span> h</span>)</span></span><br><span class="line"><span class="function"></span>		&#123;</span><br><span class="line">			width = w;</span><br><span class="line">			height = h;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>我们定义对长方形的加法： </p>
<ul>
<li>如果高度相等，则长度相加。</li>
<li>如果宽度相等，则高度相加。</li>
<li>如果都不相等，则生成一个面积和两方形面积和相等的正方形</li>
</ul>
<p><del>逻辑不重要，语法重要</del></p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> Rectangle <span class="keyword">operator</span>+(Rectangle r1, Rectangle r2)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">double</span> rw, rh;</span><br><span class="line">    <span class="keyword">if</span>(r1.Height == r2.Height)</span><br><span class="line">    &#123;</span><br><span class="line">        rh = r1.Height;</span><br><span class="line">        rw = r1.Width + r2.Width;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> Rectangle(rw, rh);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (r1.Width == r2.Width)</span><br><span class="line">    &#123;</span><br><span class="line">        rw = r1.Width;</span><br><span class="line">        rh = r1.Height + r2.Height;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> Rectangle(rw, rh);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">double</span> r = Math.Sqrt(r1.Width * r1.Height + r2.Width * r2.Height);</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> Rectangle(r, r);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>我们发现，我们可以 对 <code>Rectangle</code> 对象进行加法运算了。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Rectangle r1 = <span class="keyword">new</span> Rectangle(<span class="number">1</span>, <span class="number">2</span>);</span><br><span class="line">Rectangle r2 = <span class="keyword">new</span> Rectangle(<span class="number">1</span>, <span class="number">3</span>);</span><br><span class="line">Rectangle rectangle = r1 + r2;</span><br></pre></td></tr></table></figure>

<h3 id="对象的内置方法"><a href="#对象的内置方法" class="headerlink" title="对象的内置方法"></a>对象的内置方法</h3><p>细心的同学可能双发现了，即便是一个空对象，当我们输入 <code>.</code> 运算符，后面仍然会出现几个函数，而我们并没有对其进行声明。</p>
<p>有：</p>
<ul>
<li>Equals （判断两对象绝对相等）</li>
<li>GetHashCode （获取哈希码）</li>
<li>GetType （获取对象类型）</li>
<li>ToString  （转换为字符串）</li>
</ul>
<p>因为他们是 C# 每个类的内置函数。所有的 C# 类都是 Object 类的子类，这些是从 Object 类中继承出来的。</p>
<p>我们用最容易理解的 ToString 类作为讲解。当我们调用 <code>Console.WriteLine</code> 填入对象作为的时候，其实底层已经为我们调用了 <code>Object.ToString</code></p>
<p>我们重写 长方形 的 ToString</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">override</span> <span class="built_in">string</span> <span class="title">ToString</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">$&quot;Rectangle&#123;&#123;<span class="subst">&#123;Width&#125;</span>,<span class="subst">&#123;Height&#125;</span>&#125;&#125;&quot;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>Main 函数中可以按照我们的方式输出了。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Console.WriteLine(rectangle);</span><br></pre></td></tr></table></figure>

<h2 id="三、更多的动态多态性：接口"><a href="#三、更多的动态多态性：接口" class="headerlink" title="三、更多的动态多态性：接口"></a>三、更多的动态多态性：接口</h2><p>抽象类，其实并不是一个面向对象的优雅实现方案，本质上算是一个历史遗留问题。在C++中，由于存在多继承，抽象类可以很好的实现动态多态性。而在C#中，摒弃了难以理解的多继承概念，而使用了接口来代替实现。虽然增加了概念，但是总的来看，这使得C#的程序要比C++更加简单易懂。</p>
<p><del>说来惭愧，上节课我讲混了虚基类和抽象类，因为抽象类太难用了，老娘从来不用。</del></p>
<p>接口定义了所有类继承接口时应遵循的”语法合同”。<strong>接口定义了语法合同 “是什么” 部分，而 “怎么做” 部分则有接口的实现类决定。</strong></p>
<p>接口中可以声明方法，如果一个类想要实现这个接口，那么这个接口中所有的方法都需要被这个类实现。</p>
<h3 id="接口定义"><a href="#接口定义" class="headerlink" title="接口定义"></a>接口定义</h3><p>接口在定义的时候需要注意，在VS中需要选择 接口 而不是 类</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">interface</span> <span class="title">IMyInterface</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">MethodToImplement</span>(<span class="params"></span>)</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>Tips:   </p>
<ul>
<li>仍然符合驼峰命名，但使用大写I开头</li>
<li>接口声明不需要指定可访问性</li>
</ul>
</blockquote>
<h3 id="接口实现"><a href="#接口实现" class="headerlink" title="接口实现"></a>接口实现</h3><p>接口的实现和继承的语法类似。不同的是，一个类可以实现多个接口。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title">MyInterfaceImpl</span> : <span class="title">IMyInterface</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">MethodToImplement</span>(<span class="params"></span>) </span></span><br><span class="line"><span class="function"></span>    &#123;</span><br><span class="line">        &lt;statement&gt;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p>我们实现一个序列化接口，这个接口中我们只定义一个方法：<strong>把该对象转换为JSON</strong>（梦幻联动Java）</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">namespace</span> <span class="title">CS_ConsoleApp</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="keyword">interface</span> <span class="title">ISerializable</span></span><br><span class="line">	&#123;</span><br><span class="line">		<span class="function"><span class="built_in">string</span> <span class="title">ToJSON</span>(<span class="params"></span>)</span>; </span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>接下来，我们可以让任何一个类来实现这个接口。比如：</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title">Rectangle</span> : <span class="title">ISerializable</span></span><br></pre></td></tr></table></figure>
<p>诶，报错了！因为我们暂时还没有写入这个方法的实现。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="built_in">string</span> <span class="title">ToJSON</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">string</span> json = <span class="string">&quot;&#123;&quot;</span>;</span><br><span class="line">    json += <span class="string">&quot;\&quot;width\&quot;:\&quot;&quot;</span>+Width.ToString()+<span class="string">&quot;\&quot;,&quot;</span>;</span><br><span class="line">    json += <span class="string">&quot;\&quot;height\&quot;:\&quot;&quot;</span>+Height.ToString()+<span class="string">&quot;\&quot;&quot;</span>;</span><br><span class="line">    <span class="keyword">return</span> json+<span class="string">&quot;&#125;&quot;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这样，我们就写好了对于这个对象的 ToJSON 实现。</p>
<p>同理，任何一个类都可以实现这个 ToJSON，比如上节课的宝可梦。代码实现这里不贴出来了，很容易自己实现和理解。</p>
<h3 id="接口继承"><a href="#接口继承" class="headerlink" title="接口继承"></a>接口继承</h3><p>有趣的是，接口也存在继承。我们声明一个更牛逼的序列化，能把对象序列化为 XML 或者 JSON</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">namespace</span> <span class="title">CS_ConsoleApp</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="keyword">interface</span> <span class="title">IBetterSerializable</span> :　<span class="title">ISerializable</span></span><br><span class="line">	&#123;</span><br><span class="line">		<span class="function"><span class="built_in">string</span> <span class="title">ToXML</span>(<span class="params"></span>)</span>;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>当然，我们要同时实现两种接口</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// JSON 的略</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="built_in">string</span> <span class="title">ToXML</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">string</span> xml = <span class="string">&quot;&lt;rectangle&gt;\n&quot;</span>;</span><br><span class="line">    xml += <span class="string">&quot;\t&lt;width&gt;&quot;</span> + Width.ToString() + <span class="string">&quot;&lt;/width&gt;\n&quot;</span>;</span><br><span class="line">    xml += <span class="string">&quot;\t&lt;height&gt;&quot;</span> + Height.ToString() + <span class="string">&quot;&lt;/height&gt;\n&quot;</span>;</span><br><span class="line">    <span class="keyword">return</span> xml + <span class="string">&quot;&lt;/rectangle&gt;&quot;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<blockquote>
<p>学到这里，我希望大家已经意识到了：面向对象一大优越之处在于，无需考虑过多的细节。而 C# 的语法特性让 C# 在编写时能够有足够多的静态检查，降低我们编写程序时的记忆负担。</p>
</blockquote>
<hr>
<h2 id="四、更丰富的函数使用：参数数组"><a href="#四、更丰富的函数使用：参数数组" class="headerlink" title="四、更丰富的函数使用：参数数组"></a>四、更丰富的函数使用：参数数组</h2><p>这部分比较简单，略讲。</p>
<p>正如 <code>Console.WriteLine</code> ，我们可以用 <code>&quot;&#123;0&#125;&#123;1&#125;&#123;2&#125;&quot;</code> 这样的方式来动态输出字符串内容。我们查看这部分的源码：</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Write</span>(<span class="params"><span class="built_in">string</span> format, <span class="keyword">params</span> <span class="built_in">object</span>[] arg</span>)</span>;</span><br></pre></td></tr></table></figure>
<p>这里使用了参数数组，来保证我们可以接收到多个参数。</p>
<p>格式如下：</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> 返回类型 方法名称( <span class="keyword">params</span> 类型名称[] 数组名称 )</span><br></pre></td></tr></table></figure>
<p>很好理解，也容易使用。我们用一个给数组求和的函数举例子</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">static</span> <span class="built_in">int</span> <span class="title">AddElements</span>(<span class="params"><span class="keyword">params</span> <span class="built_in">int</span>[] arr</span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">int</span> ans = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">foreach</span>(<span class="built_in">int</span> i <span class="keyword">in</span> arr) &#123;</span><br><span class="line">        ans += i;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> ans;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>使用时，我们并不需要写入数组，只需要传入好多好多个参数就行了。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Console.WriteLine(AddElements(<span class="number">1</span>,<span class="number">23</span>,<span class="number">4</span>,<span class="number">56</span>,<span class="number">7</span>,<span class="number">89</span>,<span class="number">5</span>,<span class="number">7</span>));</span><br></pre></td></tr></table></figure>

<hr>
<h2 id="五、数据容器"><a href="#五、数据容器" class="headerlink" title="五、数据容器"></a>五、数据容器</h2><p>略讲。</p>
<p>有些人喜欢叫这个”数据结构”，我怕吓到大家，换个名字。</p>
<p>数据容器很简单，但是他的底层结构很复杂，计算机专业在大二应该会学到《数据结构》这一科目，会讲到其中很多容器的底层实现。</p>
<p>数据容器是基于泛型实现的，泛型我们会在下节课讲（我不想拖堂了），在深入学习泛型之前，理解数据容器也不难。</p>
<p>C# 中的数据容器有很多很多很多</p>
<ul>
<li>Array 我们最普通的数组，固定长度，只能存储相同的值类型</li>
<li>List 加强版数组，不定长，只能储存相同类型（不限制值类型）</li>
<li>ArrayList 超级加强版数组。不定长，可以储存乱七八糟的不同的引用类型</li>
<li>LinkedList 链表，只能储存相同类型（不限制值类型）</li>
<li>Queue 队列（链表实现）</li>
<li>Stack 栈（链表实现）</li>
<li>Set 集合 &gt; HashSet 哈希集合 SortedSet 排序集合</li>
<li>Hashtable 哈希表</li>
<li>Dictionary 字典<br><del>不全</del></li>
</ul>
<p>数据容器是对整块数据的封装。通常我们用CRUD来概括描述对数据容器的操作</p>
<ul>
<li>C ：create 增加</li>
<li>R ：retrieve 检索</li>
<li>U ：update 更新</li>
<li>D ：delete 删除</li>
</ul>
<p>我们以加强版的数组 List 为例：</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;Rectangle&gt; rectangles = <span class="keyword">new</span> List&lt;Rectangle&gt;();</span><br></pre></td></tr></table></figure>
<p>我们可以这样声明一个数据容器来使用。</p>
<p>使用 <code>.</code> 操作符，可以查看其成员变量</p>
<p><del>其实对于数据容器，短时间很难举出易于理解的具象例子。例如JavaWeb应用中，经常会有前后端交互时使用各种数据容器。所以这个部分暂时不细讲，作为了解。（而且我不想拖堂嘤嘤嘤）</del></p>
<hr>
<h2 id="完结撒花！！！"><a href="#完结撒花！！！" class="headerlink" title="完结撒花！！！"></a>完结撒花！！！</h2>
    </div>

    
    
    
        <div class="reward-container">
  <div></div>
  <button onclick="var qr = document.getElementById('qr'); qr.style.display = (qr.style.display === 'none') ? 'block' : 'none';">
    打赏
  </button>
  <div id="qr" style="display: none;">
      
      <div style="display: inline-block;">
        <img src="/images/wechatpay.png" alt="Hanamaru🍥Yabuki 微信支付">
        <p>微信支付</p>
      </div>
      
      <div style="display: inline-block;">
        <img src="/images/alipay.png" alt="Hanamaru🍥Yabuki 支付宝">
        <p>支付宝</p>
      </div>

  </div>
</div>


      <footer class="post-footer">
          
          <div class="post-tags">
              <a href="/tags/C/" rel="tag"><i class="fa fa-tag"></i> C#</a>
              <a href="/tags/%E6%8E%88%E8%AF%BE/" rel="tag"><i class="fa fa-tag"></i> 授课</a>
          </div>

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2020/11/03/%E5%8D%97%E9%82%AE%E6%A0%A1%E7%A7%91%E5%8D%8F-C-%E7%BB%84%E6%8E%88%E8%AF%BE-2/" rel="prev" title="南邮校科协-C#组授课(2)">
      <i class="fa fa-chevron-left"></i> 南邮校科协-C#组授课(2)
    </a></div>
      <div class="post-nav-item">
    <a href="/2020/11/24/%E5%8D%97%E9%82%AE%E6%A0%A1%E7%A7%91%E5%8D%8F-C-%E7%BB%84%E6%8E%88%E8%AF%BE-4/" rel="next" title="南邮校科协-C#组授课(4)">
      南邮校科协-C#组授课(4) <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E6%9B%B4%E5%A4%9A%E7%9A%84%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1-%E5%92%8C-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84"><span class="nav-number">1.</span> <span class="nav-text">更多的面向对象 和 数据结构</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E3%80%87%E3%80%81%E8%A1%A5%E5%85%85%E5%8E%86%E5%8F%B2%E9%81%97%E7%95%99%E9%97%AE%E9%A2%98"><span class="nav-number">1.1.</span> <span class="nav-text">〇、补充历史遗留问题</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#const"><span class="nav-number">1.1.1.</span> <span class="nav-text">const</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%9E%9A%E4%B8%BE"><span class="nav-number">1.1.2.</span> <span class="nav-text">枚举</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#out-%E5%BC%95%E7%94%A8%E4%BC%A0%E5%8F%82"><span class="nav-number">1.1.3.</span> <span class="nav-text">out 引用传参</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%AD%97%E6%AE%B5%E5%92%8C%E5%B1%9E%E6%80%A7"><span class="nav-number">1.1.4.</span> <span class="nav-text">字段和属性</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%B8%80%E3%80%81%E9%9D%99%E6%80%81-static"><span class="nav-number">1.2.</span> <span class="nav-text">一、静态 static</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-%E9%9D%99%E6%80%81%E6%88%90%E5%91%98"><span class="nav-number">1.2.1.</span> <span class="nav-text">1. 静态成员</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-%E9%9D%99%E6%80%81%E6%96%B9%E6%B3%95"><span class="nav-number">1.2.2.</span> <span class="nav-text">2. 静态方法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-%E9%9D%99%E6%80%81%E7%B1%BB"><span class="nav-number">1.2.3.</span> <span class="nav-text">3. 静态类</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-%E9%9D%99%E6%80%81%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0"><span class="nav-number">1.2.4.</span> <span class="nav-text">4. 静态构造函数</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BA%8C%E3%80%81%E6%9B%B4%E5%A4%9A%E7%9A%84%E9%9D%99%E6%80%81%E5%A4%9A%E6%80%81%E6%80%A7%EF%BC%9A%E8%BF%90%E7%AE%97%E7%AC%A6%E9%87%8D%E8%BD%BD-%E5%92%8C-%E5%86%85%E7%BD%AE%E6%96%B9%E6%B3%95%E9%87%8D%E8%BD%BD"><span class="nav-number">1.3.</span> <span class="nav-text">二、更多的静态多态性：运算符重载 和 内置方法重载</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%BF%90%E7%AE%97%E7%AC%A6%E9%87%8D%E8%BD%BD"><span class="nav-number">1.3.1.</span> <span class="nav-text">运算符重载</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%86%85%E7%BD%AE%E6%96%B9%E6%B3%95"><span class="nav-number">1.3.2.</span> <span class="nav-text">对象的内置方法</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%B8%89%E3%80%81%E6%9B%B4%E5%A4%9A%E7%9A%84%E5%8A%A8%E6%80%81%E5%A4%9A%E6%80%81%E6%80%A7%EF%BC%9A%E6%8E%A5%E5%8F%A3"><span class="nav-number">1.4.</span> <span class="nav-text">三、更多的动态多态性：接口</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%8E%A5%E5%8F%A3%E5%AE%9A%E4%B9%89"><span class="nav-number">1.4.1.</span> <span class="nav-text">接口定义</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%8E%A5%E5%8F%A3%E5%AE%9E%E7%8E%B0"><span class="nav-number">1.4.2.</span> <span class="nav-text">接口实现</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%8E%A5%E5%8F%A3%E7%BB%A7%E6%89%BF"><span class="nav-number">1.4.3.</span> <span class="nav-text">接口继承</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%9B%9B%E3%80%81%E6%9B%B4%E4%B8%B0%E5%AF%8C%E7%9A%84%E5%87%BD%E6%95%B0%E4%BD%BF%E7%94%A8%EF%BC%9A%E5%8F%82%E6%95%B0%E6%95%B0%E7%BB%84"><span class="nav-number">1.5.</span> <span class="nav-text">四、更丰富的函数使用：参数数组</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BA%94%E3%80%81%E6%95%B0%E6%8D%AE%E5%AE%B9%E5%99%A8"><span class="nav-number">1.6.</span> <span class="nav-text">五、数据容器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%AE%8C%E7%BB%93%E6%92%92%E8%8A%B1%EF%BC%81%EF%BC%81%EF%BC%81"><span class="nav-number">1.7.</span> <span class="nav-text">完结撒花！！！</span></a></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Hanamaru🍥Yabuki"
      src="/images/avatar.gif">
  <p class="site-author-name" itemprop="name">Hanamaru🍥Yabuki</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">13</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">5</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">7</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/HanaYabuki" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;HanaYabuki" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://space.bilibili.com/496956009" title="Bilibili → https:&#x2F;&#x2F;space.bilibili.com&#x2F;496956009" rel="noopener" target="_blank"><i class="fab fa-youtube fa-fw"></i>Bilibili</a>
      </span>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2021</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Hanamaru🍥Yabuki</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Gemini</a> 强力驱动
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/lozad@1/dist/lozad.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  
  <script>
    (function(){
      var canonicalURL, curProtocol;
      //Get the <link> tag
      var x=document.getElementsByTagName("link");
		//Find the last canonical URL
		if(x.length > 0){
			for (i=0;i<x.length;i++){
				if(x[i].rel.toLowerCase() == 'canonical' && x[i].href){
					canonicalURL=x[i].href;
				}
			}
		}
    //Get protocol
	    if (!canonicalURL){
	    	curProtocol = window.location.protocol.split(':')[0];
	    }
	    else{
	    	curProtocol = canonicalURL.split(':')[0];
	    }
      //Get current URL if the canonical URL does not exist
	    if (!canonicalURL) canonicalURL = window.location.href;
	    //Assign script content. Replace current URL with the canonical URL
      !function(){var e=/([http|https]:\/\/[a-zA-Z0-9\_\.]+\.baidu\.com)/gi,r=canonicalURL,t=document.referrer;if(!e.test(r)){var n=(String(curProtocol).toLowerCase() === 'https')?"https://sp0.baidu.com/9_Q4simg2RQJ8t7jm9iCKT-xh_/s.gif":"//api.share.baidu.com/s.gif";t?(n+="?r="+encodeURIComponent(document.referrer),r&&(n+="&l="+r)):r&&(n+="?l="+r);var i=new Image;i.src=n}}(window);})();
  </script>















  

  

</body>
</html>
